package br.edu.ufcg.greengrid.workload;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import br.edu.ufcg.greengrid.event.Event;

public class RandomMachineAvailabilityInputGenerator extends AbstractWorkloadParser {

	public RandomMachineAvailabilityInputGenerator() {
		
	}

	public void parse(String inputFileName, String outputFileName, int numMachines) throws IOException {

		File inputFile = getInputFile(inputFileName);
		File outputFile = getOutputFile(outputFileName);

		List<String> machineIds = getMachineIds(inputFile, numMachines);
		Collections.shuffle(machineIds);

		Map<String, Integer> howManyMachineInstances = new HashMap<String, Integer>();
		Set<String> machinesChosen = new HashSet<String>();
		int index = 0;

		for (index = 0; index < numMachines && index < machineIds.size(); index++) {
			machinesChosen.add(machineIds.get(index));
		}

		if (numMachines > machineIds.size()) {
			Random r = new Random();
			for (; index < numMachines; index++) {
				int i = r.nextInt(machineIds.size());
				String machineId = machineIds.get(i);
				Integer counter = howManyMachineInstances.get(machineId);
				if (counter == null) {
					counter = 1;
				}
				counter++;
				howManyMachineInstances.put(machineId, counter);
			}
		}

		generateOutput(machinesChosen, howManyMachineInstances, inputFile, outputFile);

	}

	private void generateOutput(Set<String> machinesChosen, Map<String, Integer> howManyMachineInstances,
			File inputFile, File outputFile) throws IOException {

		BufferedWriter bw = null;
		BufferedReader br = null;
		String line = null;
		
		try {
			
			bw = new BufferedWriter(new FileWriter(outputFile));
			br = new BufferedReader(new FileReader(inputFile));
			
			while ((line = br.readLine()) != null) {
				
				String[] split = line.split(Event.SEPARATOR);
				String machineId = split[0];
				if(machinesChosen.contains(machineId)){
					
					Integer counter = howManyMachineInstances.get(machineId);
					if(counter == null){
						counter = 1;
					}
					
					bw.write(line);
					bw.newLine();
					
					for (int i = 1; i < counter; i++) {
						bw.write(split[0] + String.valueOf(i) + Event.SEPARATOR + split[1] + Event.SEPARATOR + split[2]);
						bw.newLine();
					}
				}
			}
			
			
		} finally {
			if(bw != null){
				bw.close();
			}
			if(br != null){
				br.close();
			}
		}

	}

	private List<String> getMachineIds(File inputFile, int numMachines) throws IOException {

		BufferedReader br = null;
		String line = null;
		List<String> machineIds = new LinkedList<String>();

		try {
			br = new BufferedReader(new FileReader(inputFile));

			while ((line = br.readLine()) != null) {
				String machineId = line.split(Event.SEPARATOR)[0];
				machineIds.add(machineId);
			}

		} finally {
			if (br != null) {
				br.close();
			}
		}

		return new ArrayList<String>(new HashSet<String>(machineIds));
	}

}
